#include "customgraphics.h"
#include <QPainter>
#include <QGraphicsSceneMouseEvent>
#include <QMenu>
#include <QGraphicsScene>
#include <QColorDialog>
#include <QInputDialog>
#include <QDialog>
#include <QLabel>
#include <QSpinBox>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QPushButton>
#include <QGraphicsView>

// HmiComponent 基类实现
HmiComponent::HmiComponent(QGraphicsItem *parent) : QGraphicsObject(parent)
{
    setFlag(QGraphicsItem::ItemIsMovable, true);
    setFlag(QGraphicsItem::ItemIsSelectable, true);
    setAcceptHoverEvents(true);
}

void HmiComponent::setColor(const QColor& color) {
    if (m_color != color) {
        m_color = color;
        update();
    }
}

QColor HmiComponent::color() const {
    return m_color;
}

void HmiComponent::setComponentName(const QString& name) {
    m_componentName = name;
}

QString HmiComponent::componentName() const {
    return m_componentName;
}

void HmiComponent::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    Q_UNUSED(option);
    Q_UNUSED(widget);
    painter->setRenderHint(QPainter::Antialiasing);

    paintShape(painter);

    if (isSelected()) {
        painter->setBrush(Qt::NoBrush);
        painter->setPen(QPen(Qt::darkRed, 2, Qt::DashLine));
        painter->drawRect(boundingRect());
    }

    // 如果被选中，绘制缩放控制点
    if (isSelected()) {
        QRectF rect = boundingRect();

        // 绘制右下角缩放控制点
        painter->setBrush(Qt::white);
        painter->setPen(QPen(Qt::black, 1));
        painter->drawRect(rect.right() - 8, rect.bottom() - 8, 8, 8);
    }
}

void HmiComponent::setAddress(int address)
{
    if (m_address != address) {
        m_address = address;
        update();
    }
}

int HmiComponent::address() const
{
    return m_address;
}

void HmiComponent::setSize(double width, double height)
{
    prepareGeometryChange();
    m_width = width;
    m_height = height;
    update();
}

void HmiComponent::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    // 检查是否点击了缩放控制点
    if (event->button() == Qt::LeftButton && isSelected()) {
        QRectF rect = boundingRect();
        QRectF handleRect(rect.right() - 8, rect.bottom() - 8, 8, 8);

        if (handleRect.contains(event->pos())) {
            m_resizing = true;
            m_resizeStartPos = event->scenePos();
            m_resizeStartSize = QSizeF(rect.width(), rect.height());
            event->accept();
            return;
        }
    }

    // 原有的选中处理
    if (event->button() == Qt::LeftButton) {
        emit selected(this);
    }
    QGraphicsObject::mousePressEvent(event);
}

void HmiComponent::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
{
    scene()->clearSelection();
    setSelected(true);
    emit selected(this);

    QMenu menu;

    QAction *propertyAction = menu.addAction("属性");

    QAction *setOnAction = nullptr;
    QAction *setOffAction = nullptr;

    // 只有按钮才添加“置ON”和“置OFF”
    if (auto btn = dynamic_cast<HmiButton*>(this)) {
        setOnAction = menu.addAction("置ON");
        setOffAction = menu.addAction("置OFF");

        connect(setOnAction, &QAction::triggered, this, [btn]() {
            btn->setOn(true);
        });

        connect(setOffAction, &QAction::triggered, this, [btn]() {
            btn->setOn(false);
        });
    }

    menu.addSeparator();

    QAction *copyAction = menu.addAction("复制");
    QAction *deleteAction = menu.addAction("删除");

    connect(propertyAction, &QAction::triggered, this, [this]() {
        // 弹出属性对话框
        QDialog dialog;
        dialog.setWindowTitle("属性");

        QLabel* addressLabel = new QLabel("地址: ");
        QSpinBox* addressSpin = new QSpinBox();
        addressSpin->setRange(0, 4000);
        addressSpin->setValue(m_address);  // 使用当前组件地址初始化

        // ON状态颜色设置
        QLabel* onColorLabel = new QLabel("ON状态外观: ");
        // 颜色显示，用QLabel设置背景色简单示范
        QLabel* onColorDisplay = new QLabel;
        onColorDisplay->setFixedSize(40, 20);
        onColorDisplay->setAutoFillBackground(true);
        QPalette onPal = onColorDisplay->palette();
        onPal.setColor(QPalette::Window, m_onColor);
        onColorDisplay->setPalette(onPal);
        onColorDisplay->setFrameShape(QFrame::Box);

        QPushButton* onColorBtn = new QPushButton("选择颜色");

        // OFF状态颜色设置
        QLabel* offColorLabel = new QLabel("OFF状态外观: ");
        QLabel* offColorDisplay = new QLabel;
        offColorDisplay->setFixedSize(40, 20);
        offColorDisplay->setAutoFillBackground(true);
        QPalette offPal = offColorDisplay->palette();
        offPal.setColor(QPalette::Window, m_offColor);
        offColorDisplay->setPalette(offPal);
        offColorDisplay->setFrameShape(QFrame::Box);

        QPushButton* offColorBtn = new QPushButton("选择颜色");

        QObject::connect(offColorBtn, &QPushButton::clicked, [&]() {
            QColor color = QColorDialog::getColor(m_offColor, nullptr, "选择 OFF 状态颜色");
            if (color.isValid()) {
                m_offColor = color;
                QPalette pal = offColorDisplay->palette();
                pal.setColor(QPalette::Window, color);
                offColorDisplay->setPalette(pal);
                offColorDisplay->update();
                setColor(color); // 默认显示OFF状态颜色
            }
        });

        // 地址布局
        QHBoxLayout* addressLayout = new QHBoxLayout();
        addressLayout->addWidget(addressLabel);
        addressLayout->addWidget(addressSpin);

        // ON颜色布局
        QHBoxLayout* onColorLayout = new QHBoxLayout();
        onColorLayout->addWidget(onColorLabel);
        onColorLayout->addWidget(onColorDisplay);
        onColorLayout->addWidget(onColorBtn);

        // OFF颜色布局
        QHBoxLayout* offColorLayout = new QHBoxLayout();
        offColorLayout->addWidget(offColorLabel);
        offColorLayout->addWidget(offColorDisplay);
        offColorLayout->addWidget(offColorBtn);

        // 确定/取消按钮
        QPushButton* okBtn = new QPushButton("确定");
        QPushButton* cancelBtn = new QPushButton("取消");
        QHBoxLayout* btnLayout = new QHBoxLayout();
        btnLayout->addStretch();
        btnLayout->addWidget(okBtn);
        btnLayout->addWidget(cancelBtn);

        // 颜色选择按钮点击槽
        QObject::connect(onColorBtn, &QPushButton::clicked, [&]() {
            QColor color = QColorDialog::getColor(m_onColor, nullptr, "选择 ON 状态颜色");
            if (color.isValid()) {
                m_onColor = color;
                QPalette pal = onColorDisplay->palette();
                pal.setColor(QPalette::Window, color);
                onColorDisplay->setPalette(pal);
                onColorDisplay->update();
            }
        });

        QVBoxLayout* mainLayout = new QVBoxLayout();
        mainLayout->addLayout(addressLayout);
        mainLayout->addLayout(onColorLayout);
        mainLayout->addLayout(offColorLayout);
        mainLayout->addLayout(btnLayout);

        dialog.setLayout(mainLayout);

        // 关闭逻辑
        QObject::connect(okBtn, &QPushButton::clicked, [&]() {
            // 保存地址
            int newAddress = addressSpin->value();
            setAddress(newAddress);

            // 已经在onColorBtn / offColorBtn中修改了m_onColor / m_offColor，需要触发界面更新
            update();
            dialog.accept();
        });
        QObject::connect(cancelBtn, &QPushButton::clicked, &dialog, &QDialog::reject);

        dialog.exec();
    });

    connect(copyAction, &QAction::triggered, this, [this]() {
        emit copyRequested(this);
    });

    connect(deleteAction, &QAction::triggered, this, [this]() {
        emit deleteRequested(this);
    });

    menu.exec(event->screenPos());
}

void HmiComponent::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    if (m_resizing) {
        // 计算尺寸变化
        QPointF delta = event->scenePos() - m_resizeStartPos;
        double newWidth = qMax(20.0, m_resizeStartSize.width() + delta.x());
        double newHeight = qMax(20.0, m_resizeStartSize.height() + delta.y());

        // 更新组件大小
        prepareGeometryChange();

        // 子类需要实现setSize函数
        setSize(newWidth, newHeight);

        // 更新缩放控制点位置
        update();
        event->accept();
        return;
    }

    if (!(flags() & QGraphicsItem::ItemIsMovable)) {
        // 如果项不可移动，直接调用基类处理
        QGraphicsObject::mouseMoveEvent(event);
        return;
    }

    // 计算拖动后的位置
    QPointF delta = event->scenePos() - event->lastScenePos();
    QPointF newPos = pos() + delta;

    // 获取视图（假设只有1个视图）
    QList<QGraphicsView*> views = scene()->views();
    if (views.isEmpty()) {
        // 没有视图则默认处理
        QGraphicsObject::mouseMoveEvent(event);
        return;
    }
    QGraphicsView* view = views.first();

    // 获取视口矩形（像素坐标）
    QRect viewportRect = view->viewport()->rect();

    // 将视口矩形映射到场景坐标
    QPointF topLeftScene = view->mapToScene(viewportRect.topLeft());
    QPointF bottomRightScene = view->mapToScene(viewportRect.bottomRight());
    QRectF visibleSceneRect(topLeftScene, bottomRightScene);

    // 组件的边界矩形（局部坐标）
    QRectF bounds = boundingRect();

    // 计算移动后组件边界矩形（在场景坐标）
    QRectF newBounds = bounds.translated(newPos);

    // 限制组件边界必须完全在视图可见区域内
    double limitedX = newPos.x();
    double limitedY = newPos.y();

    if (newBounds.left() < visibleSceneRect.left())
        limitedX += visibleSceneRect.left() - newBounds.left();
    if (newBounds.top() < visibleSceneRect.top())
        limitedY += visibleSceneRect.top() - newBounds.top();
    if (newBounds.right() > visibleSceneRect.right())
        limitedX -= newBounds.right() - visibleSceneRect.right();
    if (newBounds.bottom() > visibleSceneRect.bottom())
        limitedY -= newBounds.bottom() - visibleSceneRect.bottom();

    setPos(QPointF(limitedX, limitedY));
    event->accept();
}

void HmiComponent::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    if (m_resizing && event->button() == Qt::LeftButton) {
        m_resizing = false;
        event->accept();
        return;
    }
    QGraphicsObject::mouseReleaseEvent(event);
}

void HmiComponent::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
{
    QRectF rect = boundingRect();
    QRectF handleRect(rect.right() - 8, rect.bottom() - 8, 8, 8);

    if (isSelected() && handleRect.contains(event->pos())) {
        setCursor(Qt::SizeFDiagCursor);
        m_resizeHandle = BottomRight;
    } else {
        setCursor(Qt::ArrowCursor);
        m_resizeHandle = None;
    }
    QGraphicsObject::hoverMoveEvent(event);
}

void HmiComponent::setOnColor(const QColor& color) {
    m_onColor = color;
}

void HmiComponent::setOffColor(const QColor& color) {
    m_offColor = color;
    setColor(color); // 默认展示 OFF 状态颜色
}

QColor HmiComponent::onColor() const {
    return m_onColor;
}

QColor HmiComponent::offColor() const {
    return m_offColor;
}


HmiButton::HmiButton(QGraphicsItem *parent) : HmiComponent(parent), m_isOn(false)
{
    // 按钮保持矩形形状
    m_width = 65.0;
    m_height = 30.0;
    m_color = Qt::gray;
    m_offColor = m_color;     // OFF状态颜色设为默认颜色
    m_onColor = Qt::green;    // ON状态颜色为绿色
    m_componentName = "Button";
    setColor(m_offColor);     // 当前显示OFF颜色
}

void HmiButton::setSize(double width, double height)
{
    HmiComponent::setSize(width, height);
}

bool HmiButton::isOn() const
{
    return m_isOn;
}

void HmiButton::setOn(bool on)
{
    if (m_isOn != on) {
        m_isOn = on;
        if (m_isOn)
            setColor(m_onColor);
        else
            setColor(m_offColor);
        emit stateChanged(m_isOn); // 通知 HMIModule 更新
        update();
    }
}

QRectF HmiButton::boundingRect() const
{
    return QRectF(0, 0, m_width, m_height);
}

void HmiButton::paintShape(QPainter *painter)
{
    painter->setPen(Qt::NoPen);
    painter->setBrush(m_isOn ? m_onColor : m_offColor);
    painter->drawRect(boundingRect());
}

void HmiButton::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    // 让基类处理其他情况（选择、拖动等）
    HmiComponent::mousePressEvent(event);
}

HmiIndicator::HmiIndicator(QGraphicsItem *parent) : HmiComponent(parent)
{
    // 指示灯初始为圆形
    m_width = 30.0;
    m_height = 30.0;
    m_color = Qt::red;
    m_offColor = m_color;     // OFF状态颜色设为默认颜色
    m_onColor = Qt::green;    // ON状态颜色为绿色
    m_componentName = "Indicator";
    setColor(m_offColor);     // 当前显示OFF颜色
}

void HmiIndicator::setSize(double width, double height)
{
    HmiComponent::setSize(width, height);
}

QRectF HmiIndicator::boundingRect() const
{
    return QRectF(0, 0, m_width, m_height);
}


void HmiIndicator::paintShape(QPainter *painter)
{
    painter->setPen(Qt::NoPen);
    painter->setBrush(m_color);
    painter->drawEllipse(boundingRect());
}
